﻿using System;
using System.Collections.Generic;
using System.IO;
using Luna.Connectors;

namespace Luna.Model.Configuration
{
    public class LunaConfigurationService : LunaService, IConfigurationService
    {
        private Dictionary<ConnectorType, IConnectorConfiguration> _ConnectorConfigurations = new Dictionary<ConnectorType, IConnectorConfiguration>();
        private DatabaseDescriptor _Current;

        public LunaConfigurationService()
        {
            _Current = new DatabaseDescriptor();
        }

        public IDictionary<ConnectorType, IConnectorConfiguration> ConnectorConfigurations
        {
            get { return _ConnectorConfigurations; }
        }

        public IDatabaseDescriptor Current
        {
            get { return _Current; }
        }

        public void Configure(IConnectorConfiguration P_Connector)
        {
            ConnectorConfiguration L_Configuration = P_Connector as ConnectorConfiguration;
            DataContext.Configuration.SaveConnector(L_Configuration.Data);

            var L_Connector = DataContext.Connectors[L_Configuration.Type];
            L_Connector.Configure(P_Connector);
            L_Configuration.Enabled = L_Connector.Enabled;
            _ConnectorConfigurations[L_Configuration.Type] = L_Configuration;
        }

        public void Disable(IConnectorConfiguration P_Connector)
        {
            throw new NotImplementedException();
        }

        public string Test(IConnectorConfiguration P_Connector)
        {
            return DataContext.Connectors[P_Connector.Type].Test(P_Connector);
        }

        private void InitializeConnectors()
        {
            _ConnectorConfigurations.Clear();
            foreach (var L_Connector in DataContext.Connectors.Values)
            {
                L_Connector.ResetConfig();
                IConnectorConfiguration L_Configuration = ConnectorConfiguration.Create(L_Connector);
                _ConnectorConfigurations[L_Configuration.Type] = L_Configuration;
            }
        }

        #region Database

        public void New()
        {
            DataContext.Configuration.CreateNewStore(Path.GetTempFileName() + ".mdf");

            _Current.CurrentFile = "New";

            /*IConnectorData L_Data = DataContext.Create<IConnectorData>();
            L_Data.Login = "ycarpent@gmail.com";
            L_Data.Password = "28cyriletlea&";
            DataContext.Connectors[ConnectorType.Google].Configure(L_Data);*/
            InitializeConnectors();

            // _ConnectorConfigurations[ConnectorType.Google].Login = "ycarpent@gmail.com";
            // _ConnectorConfigurations[ConnectorType.Google].Password = "28cyriletlea&";

            OnDatabaseChanged(EventArgs.Empty);
        }

        public void Open(string P_FileName)
        {
            // Open database
            DataContext.Configuration.OpenExistingStore(P_FileName);

            InitializeConnectors();

            // Configure connectors
            foreach (var L_ConnectorConfiguration in DataContext.Configuration.GetAllConnectors())
            {
                var L_Connector = DataContext.Connectors[L_ConnectorConfiguration.Type];
                var L_Config = ConnectorConfiguration.Create(L_Connector, L_ConnectorConfiguration);
                L_Connector.Configure(L_Config);
                _ConnectorConfigurations[L_Config.Type] = L_Config;
            }

            // Set current database description
            _Current.CurrentFile = P_FileName;
            OnDatabaseChanged(EventArgs.Empty);
        }

        public void SaveAs(string P_FileName)
        {
            DataContext.Configuration.MoveCurrentStoreTo(P_FileName);

            _Current.CurrentFile = P_FileName;
        }

        #region DatabaseChanged

        public event EventHandler DatabaseChanged;

        protected virtual void OnDatabaseChanged(EventArgs e)
        {
            EventHandler L_Handler = DatabaseChanged;

            if (L_Handler != null)
            {
                L_Handler(this, e);
            }
        }

        #endregion DatabaseChanged

        #endregion Database
    }
}